package com.pxst.merchant.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.pxst.agent.mapper.SysAgentsMapper;
import com.pxst.merchant.constants.SysMerchantAvailableBankEntityConstants;
import com.pxst.merchant.entity.SysMerchantAvailableBankEntity;
import com.pxst.merchant.entity.SysMerchantInfo;
import com.pxst.merchant.mapper.SysMerchantAvailableBankMapper;
import com.pxst.merchant.mapper.SysMerchantInfoMapper;
import com.pxst.merchant.req.MerchantInfoReq;
import com.pxst.merchant.req.MerchantListReq;
import com.pxst.merchant.resp.MerchantInfoResp;
import com.pxst.merchant.resp.MerchantListResp;
import com.pxst.merchant.resp.MerchantSelectListResp;
import com.pxst.merchant.service.SysMerchantAvailableBankService;
import com.pxst.merchant.service.SysMerchantInfoService;
import com.pxst.resp.ApiResp;
import com.pxst.resp.PageResp;
import icu.mhb.mybatisplus.plugln.base.service.impl.JoinServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/** 
* @author yangxy
* @version 创建时间：2023年9月12日 上午11:16:44 
*/
@Service
public class SysMerchantInfoServiceImpl extends JoinServiceImpl<SysMerchantInfoMapper, SysMerchantInfo> implements SysMerchantInfoService {

    @Autowired
    private SysMerchantInfoMapper sysMerchantInfoMapper;

    @Autowired
    private SysMerchantAvailableBankService sysMerchantAvailableBankService;

    @Autowired
    private SysMerchantAvailableBankMapper sysMerchantAvailableBankMapper;

    @Autowired
    private SysAgentsMapper sysAgentsMapper;




    @Override
    public ApiResp<List<MerchantSelectListResp>> getMerchantSelectList() {
        return ApiResp.sucess(sysMerchantInfoMapper.getMerchantSelectList());
    }


    @Override
    public ApiResp<PageResp<MerchantListResp>> getMerchantInfoList(MerchantListReq param) throws NoSuchFieldException, IllegalAccessException {

        // 需要计算total的列
        List<String> columnNameList = new ArrayList<>();
        columnNameList.add("balance");
        columnNameList.add("freezeBalance");
        columnNameList.add("availableBalance");
        columnNameList.add("todayTrFee");
        columnNameList.add("waitIncomeAmount");
        columnNameList.add("frozenBalanceAj");


        List<MerchantListResp> allList = sysMerchantInfoMapper.getMerchantInfoList(param);
        int start = (param.getPage()-1) * param.getRp();
        List<MerchantListResp> pageList = allList.stream().skip(start).limit(param.getRp()).collect(Collectors.toList());
        Map<String, BigDecimal> totals = computeTotal(allList, columnNameList);
        Map<String, BigDecimal> subTotal = computeTotal(pageList, columnNameList);
        return ApiResp.page(param.getPage(),param.getRp(),allList.size(),pageList,subTotal,totals);
    }

    /**
     * -Author: @Ryan
     * -Description: 计算传入集合的指定字段的合计
     * -Param: objList- 需要计算合计的集合
     *         columnNameList- 需要计算的对象中的字段名称列表
     * -return: java.util.Map<java.lang.String,java.math.BigDecimal>
     **/
    public <T> Map<String, BigDecimal> computeTotal(List<T> objList, List<String> columnNameList) throws NoSuchFieldException, IllegalAccessException {
        HashMap<String, BigDecimal> totalMap = new HashMap<>();
        if (columnNameList.isEmpty()){
            return totalMap;
        }
        for (String columnName :columnNameList) {
            BigDecimal columnTotal = new BigDecimal("0");
            for (T obj:objList) {
                Field field = obj.getClass().getDeclaredField(columnName);

                field.setAccessible(true);
                BigDecimal val = (BigDecimal) field.get(obj);
                if (val == null){
                    continue;
                }else {
                    columnTotal = columnTotal.add(val);
                }
            }
            totalMap.put(columnName,columnTotal);
        }
        return totalMap;
    }

    @Override
    public ApiResp<MerchantInfoResp> addMerchant(MerchantInfoReq merchantInfo)  {
        // 商户名称、商户code是否存在
        QueryWrapper<SysMerchantInfo> infoQueryWrapper = new QueryWrapper<>();
        infoQueryWrapper.eq("name",merchantInfo.getName());
        List<SysMerchantInfo> nameExsitList = sysMerchantInfoMapper.selectList(infoQueryWrapper);
        if (!nameExsitList.isEmpty()){
            return ApiResp.paramError("商户名称已存在，请重新输入");
        }
        infoQueryWrapper.clear();
        infoQueryWrapper.eq("code",merchantInfo.getCode());
        List<SysMerchantInfo> codeExsitList = sysMerchantInfoMapper.selectList(infoQueryWrapper);
        if (!codeExsitList.isEmpty()){
            return ApiResp.paramError("商户编码已存在，请重新输入");
        }
        //判断设定的最大值是否大于最小值
        if (
                merchantInfo.getFoMax().compareTo(merchantInfo.getFoMin()) == -1 ||
                        merchantInfo.getFiTwMax().compareTo(merchantInfo.getFiTwMin()) == -1 ||
                        merchantInfo.getFiQrMax().compareTo(merchantInfo.getFiQrMin())  == -1 ||
                        merchantInfo.getFxMax().compareTo(merchantInfo.getFxMin())  == -1 ||
                        merchantInfo.getFiBankMax().compareTo(merchantInfo.getFiBankMin()) == -1
        ) {
            return ApiResp.paramError("设定的最大值小于了最小值");
        }
        // 判断可用银行是否为空
        SysMerchantInfo sysMerchantInfo = new SysMerchantInfo();

        // 将接收到的对象分别封装给商户对象，和商户可用银行对象中
        Field[] fields = sysMerchantInfo.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            try {
                field.set(sysMerchantInfo,field.get(merchantInfo));
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
        // 设置商户的secret编码 **
        sysMerchantInfo.setSecret("MI6vw7EyInK7kPSD2FsDBw==");
        //设置网站 **
        sysMerchantInfo.setWebSite("api-tg-outside.100scrop.tech/165-d7e");

        sysMerchantInfoMapper.insert(sysMerchantInfo);
        Long merchantId = sysMerchantInfo.getId();
        if (merchantInfo.getOpenBank() != null && !merchantInfo.getOpenBank().isEmpty()){
            for (SysMerchantAvailableBankEntity merchantavail :
                    merchantInfo.getOpenBank()) {
                merchantavail.setMerchantId(merchantId);
                sysMerchantAvailableBankService.addSysMerchantAvailableBank(merchantavail);
            }
        }
        return ApiResp.sucess(sysMerchantInfo);
    }

    @Override
    public ApiResp updateMerchant(MerchantInfoReq merchantInfoReq) {
        //判断修改后的name、code是否唯一
        SysMerchantInfo merchantInfo = null;
        QueryWrapper<SysMerchantInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("name",merchantInfoReq.getName());
        merchantInfo = sysMerchantInfoMapper.selectOne(wrapper);
        if (merchantInfo != null ){
            if (!merchantInfo.getId().equals (merchantInfoReq.getId())) {
                return ApiResp.paramError("商户名称已存在");
            }
        }
        wrapper.clear();
        wrapper.eq("code",merchantInfoReq.getCode());
        merchantInfo = sysMerchantInfoMapper.selectOne(wrapper);
        if (merchantInfo != null ){
            if(!merchantInfo.getId().equals(merchantInfoReq.getId())) {
                return ApiResp.paramError("商户编码已存在");
            }
        }
        SysMerchantInfo sysMerchantInfo = new SysMerchantInfo();
        // 将接收到的对象分别封装给商户对象，和商户可用银行对象中
        Field[] fields = sysMerchantInfo.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            try {
                field.set(sysMerchantInfo,field.get(merchantInfoReq));
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
        sysMerchantInfoMapper.updateById(sysMerchantInfo);
        if (merchantInfoReq.getOpenBank() != null && !merchantInfoReq.getOpenBank().isEmpty()){
            for (SysMerchantAvailableBankEntity merchantAvail : merchantInfoReq.getOpenBank()) {
                if (
                        merchantAvail.getEnabled().equals(SysMerchantAvailableBankEntityConstants.BANK_DISABLE)
                                && "".equals(merchantAvail.getMessage())
                ){
                    return ApiResp.paramError("设置商户银行不可用时，必须给出不可有提示信息");
                }
                sysMerchantAvailableBankService.updateSysMerchantAvailableBank(merchantAvail);
            }
        }
        return ApiResp.sucess();
    }

    @Override
    public ApiResp<MerchantInfoResp> getMerchantInfoById(Long id) {
        SysMerchantInfo merchant = sysMerchantInfoMapper.selectById(id);
        if(merchant == null){
            return ApiResp.paramError("该商户不存在");
        }
        MerchantInfoResp merchantInfoResp = new MerchantInfoResp();
        Field[] fields = merchant.getClass().getDeclaredFields();
        for (Field field :fields) {
            field.setAccessible(true);
            try {
                field.set(merchantInfoResp,field.get(merchant));
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
        QueryWrapper<SysMerchantAvailableBankEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("merchant_id",id);
        merchantInfoResp.setOpenBank(sysMerchantAvailableBankMapper.selectList(wrapper)) ;
        return ApiResp.sucess(merchantInfoResp);
    }




}
